package com.morizhang.merchanmanager.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.morizhang.merchanmanager.api.bean.ApiDefinitionHolder;
import com.morizhang.merchanmanager.api.bean.ErrorDefinition;
import com.morizhang.merchanmanager.api.bean.ErrorDefinitionHolder;
import com.morizhang.merchanmanager.api.bean.MerChanManagerException;
import com.morizhang.merchanmanager.api.dao.UserDao;
import com.morizhang.merchanmanager.api.model.UserModel;
import com.morizhang.merchanmanager.api.utils.ErrorUtils;
import com.morizhang.merchanmanager.api.utils.ServiceAuthorityChecker;
import com.morizhang.merchanmanager.api.utils.UserSystemAgent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@RestController
public class ApiController extends AbstractApiController {

    @RequestMapping("/api")
    public ResponseEntity<Object> api(HttpSession session, HttpServletRequest request, @RequestBody String requestParams) {
        //HttpSession session = request.getSession();
        ApiParams apiParams = createApiParams(request, requestParams);
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);

        JSONObject paramJson;
        String requestService;

        try {
            //检查传入格式
            requestValidate(requestParams);
            paramJson = JSONObject.parseObject(requestParams, Feature.OrderedField);
            requestService = paramJson.getString("requestService");
            //检查调用权限
            String userID = (String)session.getAttribute("userID");
            //未登录
            if (userID == null) {
                MerChanManagerException exception = new MerChanManagerException();
                ErrorDefinition error = ErrorDefinitionHolder.get("NOT_LOGIN");
                exception.setErrorDefinition(error);
                throw exception;
            }
            //越权访问
            if (!ServiceAuthorityChecker.checkAuthority(userID, requestService)) {
                MerChanManagerException exception = new MerChanManagerException();
                ErrorDefinition error = ErrorDefinitionHolder.get("INVALID_AUTHORITY");
                exception.setErrorDefinition(error);
                throw exception;
            }
        } catch (MerChanManagerException merChanManagerException) {
            ErrorDefinition error = merChanManagerException.getErrorDefinition();
            JSONObject responseData = ErrorUtils.convertErrorToJsonForm(error);
            responseData.put("isSuccess", "fail");
            return new ResponseEntity<Object>(responseData, headers, HttpStatus.BAD_REQUEST);
        }
        IService service = ApiDefinitionHolder.get(requestService);
        ApiResult result = null;
        try {
            result = service.callService(apiParams.getRequestParams());
        } catch (Exception exception) {
            exception.printStackTrace();
        }

        if (result.isSuccess()) {
            JSONObject responseData = new JSONObject();
            responseData.put("isSuccess", "success");
            responseData.put("data", result.getData());
            return new ResponseEntity<Object>(responseData, headers, HttpStatus.OK);
        } else {
            ErrorDefinition error = result.getException().getErrorDefinition();
            JSONObject responseData = ErrorUtils.convertErrorToJsonForm(error);
            responseData.put("isSuccess", "fail");
            return new ResponseEntity<Object>(responseData, headers, HttpStatus.BAD_REQUEST);
        }
    }

    private void requestValidate(String requestParams) throws MerChanManagerException {
        JSONObject paramJson;
        try {
            paramJson = JSONObject.parseObject(requestParams, Feature.OrderedField);
        }
        catch (JSONException jsonException) {
            ErrorDefinition error = ErrorDefinitionHolder.get("INVALID_FORM");
            MerChanManagerException merChanManagerException = new MerChanManagerException();
            merChanManagerException.setErrorDefinition(error);
            throw merChanManagerException;
        }
        if (paramJson.get("requestService") == null) {
            ErrorDefinition error = ErrorDefinitionHolder.get("NO_REQUEST_SERVICE");
            MerChanManagerException merChanManagerException = new MerChanManagerException();
            merChanManagerException.setErrorDefinition(error);
            throw merChanManagerException;
        }
        if (paramJson.get("requestMethod") == null) {
            ErrorDefinition error = ErrorDefinitionHolder.get("NO_REQUEST_METHOD");
            MerChanManagerException merChanManagerException = new MerChanManagerException();
            merChanManagerException.setErrorDefinition(error);
            throw merChanManagerException;
        }
        if (paramJson.get("data") == null) {
            ErrorDefinition error = ErrorDefinitionHolder.get("NO_DATA");
            MerChanManagerException merChanManagerException = new MerChanManagerException();
            merChanManagerException.setErrorDefinition(error);
            throw merChanManagerException;
        }
    }

}
